﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Text.RegularExpressions;

namespace Hugo
{
    public abstract class UIPage : UIOption
    {
        
        public MainWindow MainWindow { get; set;  }
        public Canvas ParentCanvas { get; set; }
        public Canvas PageCanvas { get; set; }

        static int nextPageCanvasID = 0;

        static int counter = 0;

        bool navigationComponentsVisible = true;

        public const int ICON_WIDTH_SELECTED = 150;
        public const int ICON_HEIGHT_SELECTED = ICON_WIDTH_SELECTED;
        public const double ICON_OPACITY_SELECTED = 1.0;
        public const double ICON_OPACITY_UNSELECTED = 0.15;
        public const int ICON_BUFFER = 0;

        List<UIOption> pageOptions;
        Dictionary<String, Rectangle> pageNameToIconMap;
        Dictionary<String, UIOption> pageNameToOptionMap;

        public UIPage(String name, BitmapSource iconSource) : base(name,iconSource)
        {
            this.MainWindow = MainWindow.getInstance();
            //this.Name = name;
            this.IconSource = iconSource;
            this.ParentCanvas = this.MainWindow.mainCanvas;
            PageCanvas = new Canvas();
            PageCanvas.Name = name.Replace(" ","") + "_pagecanvas" + (nextPageCanvasID++);
            this.MainWindow.RegisterName(PageCanvas.Name, PageCanvas);  
            ParentCanvas.Children.Add(PageCanvas);
            PageCanvas.Opacity = 0;

            

            pageOptions = new List<UIOption>();
            this.pageNameToIconMap = new Dictionary<String, Rectangle>();
            this.pageNameToOptionMap = new Dictionary<String, UIOption>();
        }

        public override void wasSelected() {
            MainWindow.pushPage(this);
        }

        public virtual void setPage()
        {
            DoubleAnimation myDoubleAnimation = AnimationFactory.getFadeInAnimation();

            Storyboard myStoryboard = new Storyboard();
            myStoryboard.Children.Add(myDoubleAnimation);
            Storyboard.SetTargetName(myDoubleAnimation, PageCanvas.Name);
            Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Canvas.OpacityProperty));

            myStoryboard.Begin(this.MainWindow);
        }

        public abstract void respondToKey(KeyEventArgs e);

        int cursorCountDown;
        const int HOLD_TIME = 50; 
        String selectedOptionName;
        Rectangle selectedRectangle;
        
        public virtual void setCursorPosition(Point p)
        {
            bool isOverSomething = false;

            foreach (String pageName in pageNameToIconMap.Keys)
            {

                Rectangle r = pageNameToIconMap[pageName];
                double rX = Canvas.GetLeft(r);// + currentpos;
                double rY = Canvas.GetTop(r);// -verticalBuffer;
                double rX2 = rX + r.ActualWidth;
                double rY2 = rY + r.ActualHeight;// +verticalBuffer * 2;

                if (rX < p.X && rY < p.Y && rX2 > p.X && rY2 > p.Y)
                {
                    isOverSomething = true;

                    if (selectedOptionName == null || !selectedOptionName.Equals(pageName))
                    {
                        if (selectedRectangle != null)
                        {
                            this.selectedRectangle.Opacity = ICON_OPACITY_UNSELECTED;
                        }


                        Sounds.playSound(Sounds.Sound.Navigate);
                        
                        selectedRectangle = r;
                        selectedOptionName = pageName;
                        r.Opacity = ICON_OPACITY_SELECTED;

                        //startFlashing(selectedRectangle);

                        cursorCountDown = HOLD_TIME;
                    }

                    cursorCountDown--;

                    if (cursorCountDown == 0)
                    {
                        pageNameToOptionMap[pageName].wasSelected();
                        selectedOptionName = null;
                    }
                }
            }

            if (!isOverSomething)
            {
                if (flashAnimationStoryboard != null)
                {
                    //flashAnimationStoryboard.Stop(this.MainWindow);
                    this.selectedRectangle.Opacity = ICON_OPACITY_UNSELECTED;
                    this.selectedRectangle = null;
                    this.selectedOptionName = null;
                }
            }
        }

        Storyboard flashAnimationStoryboard;

        public void startFlashing(Rectangle r)
        {

            if (flashAnimationStoryboard != null)
            {
                flashAnimationStoryboard.Stop(this.MainWindow);
            }

            DoubleAnimation flashAnimation = AnimationFactory.getFastContinuousFadeAnimation(ICON_OPACITY_SELECTED, ICON_OPACITY_SELECTED * 0.4);

            flashAnimationStoryboard = new Storyboard();
            flashAnimationStoryboard.Children.Add(flashAnimation);
            Storyboard.SetTargetName(flashAnimation, r.Name);
            Storyboard.SetTargetProperty(flashAnimation, new PropertyPath(Canvas.OpacityProperty));

            flashAnimationStoryboard.Begin(this.MainWindow, true);
        }

        public virtual void unSetPage()
        {
            DoubleAnimation myDoubleAnimation = AnimationFactory.getFadeOutAnimation();

            Storyboard myStoryboard = new Storyboard();
            myStoryboard.Children.Add(myDoubleAnimation);
            Storyboard.SetTargetName(myDoubleAnimation, PageCanvas.Name);
            Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Canvas.OpacityProperty));

            myStoryboard.Begin(this.MainWindow);
        }

        int layoutScheme = 3;
        //int controlsOffset = GlobalSettings.isRightHanded ? (GlobalSettings.ScreenMiddleX/2) : (-GlobalSettings.ScreenMiddleX / 2);

        int controlsOffset = GlobalSettings.isRightHanded ? 170 : -170-3*(ICON_BUFFER+ICON_WIDTH_SELECTED);

        public void addNavigationUIOptions(List<UIOption> options)
        {
            
            int middle = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / 2;
            double navIconY = GlobalSettings.NavigationIconsBaseLineY;

            double startX = middle - (((double)options.Count) / 2) * ICON_WIDTH_SELECTED + (options.Count / 2) * ICON_BUFFER;

            int i = 0;
            foreach (UIOption o in options)
            {
                this.pageOptions.Add(o);
                Rectangle rect = getSymbol(o.IconSource);   
                PageCanvas.Children.Add(rect);

                if (layoutScheme == 0)
                {
                    Canvas.SetLeft(rect, startX + ICON_WIDTH_SELECTED * i + ICON_BUFFER * i);
                    Canvas.SetTop(rect, navIconY);
                }
                else if (layoutScheme == 1)
                {
                    
                    switch (i)
                    {
                        case 0:
                        case 1:
                        case 2:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX + controlsOffset + i * (ICON_WIDTH_SELECTED + ICON_BUFFER));
                            Canvas.SetTop(rect, navIconY);
                            break;
                        case 3:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX + controlsOffset + 1 * (ICON_BUFFER + ICON_WIDTH_SELECTED));
                            Canvas.SetTop(rect, navIconY - ICON_BUFFER - ICON_HEIGHT_SELECTED);
                            break;
                            
                    }
                }
                else if (layoutScheme == 2)
                {
                    controlsOffset = -(3 * ICON_WIDTH_SELECTED / 2 + ICON_BUFFER);

                    switch (i)
                    {
                        case 0:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX + controlsOffset + -ICON_WIDTH_SELECTED - 10);
                            Canvas.SetTop(rect, navIconY);
                            break;
                        case 1:
                        case 2:
                        case 3:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX + controlsOffset + (i - 1) * (ICON_WIDTH_SELECTED + ICON_BUFFER));
                            Canvas.SetTop(rect, navIconY);
                            break;
                        case 4:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX + controlsOffset + (i - 1) * (ICON_BUFFER + ICON_WIDTH_SELECTED) + 10);
                            Canvas.SetTop(rect, navIconY);
                            break;
                    }
                }
                else
                {
                    int bbuffer = 150;
                    controlsOffset = -(3 * ICON_WIDTH_SELECTED / 2 + bbuffer);

                    switch (i)
                    {
                        case 0:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX -ICON_WIDTH_SELECTED - 10);
                            Canvas.SetTop(rect, navIconY);
                            break;
                        case 1:
                        case 2:
                        case 3:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX + controlsOffset + (i - 1) * (ICON_WIDTH_SELECTED + bbuffer));
                            Canvas.SetTop(rect, navIconY-260);
                            break;
                        case 4:
                            Canvas.SetLeft(rect, GlobalSettings.ScreenMiddleX + 10);
                            Canvas.SetTop(rect, navIconY);
                            break;
                    }
                }
                
                rect.Opacity = ICON_OPACITY_UNSELECTED;

                Regex rgx = new Regex("[^a-zA-Z0-9]");

                rect.Name = "tileuinavpage" + (counter++) + "_rect";
                this.MainWindow.RegisterName(rect.Name, rect);

                pageNameToIconMap.Add(rect.Name, rect);
                pageNameToOptionMap.Add(rect.Name, o);
                
                i++;
            }
        }

        public static Rectangle getSymbol(BitmapSource u)
        {
            return Util.getSymbol(u, ICON_WIDTH_SELECTED, ICON_HEIGHT_SELECTED);
        } 

        public void setNavigationComponentsVisible(bool b)
        {
            this.navigationComponentsVisible = b;
            foreach (String pageName in pageNameToIconMap.Keys)
            {
                Rectangle r = pageNameToIconMap[pageName];
                if (b)
                {
                    r.Opacity = 1;
                }
                else
                {
                    r.Opacity = 0;
                }
            }
        }
    }
}
